:art: Field Pool

huangqimin001 3 years ago
parent
commit
db63fb02fa

+ 38 - 0
api/field_views.py

@@ -0,0 +1,38 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+from __future__ import division
4
+
5
+from django_logit import logit
6
+from django_query import get_query_value
7
+from django_response import response
8
+
9
+from api.wx_views import get_point_limit_scene_qrcode_url
10
+from equipment.models import IsolationPointFieldPoolInfo, IsolationPointInfo
11
+from utils.error.errno_utils import IsolationPointStatusCode
12
+
13
+
14
+@logit
15
+def field_default(request):
16
+    fields = IsolationPointFieldPoolInfo.objects.filter(status=True)
17
+    fields = [f.data for f in fields]
18
+
19
+    return response(data={
20
+        'fields': fields,
21
+    })
22
+
23
+
24
+@logit
25
+def point_field_update(request):
26
+    point_id = request.POST.get('point_id', '')
27
+    fields = get_query_value(request, 'fields', val_cast_type='listjson')
28
+
29
+    try:
30
+        point = IsolationPointInfo.objects.get(point_id=point_id, status=True)
31
+    except IsolationPointInfo.DoesNotExist:
32
+        return response(IsolationPointStatusCode.ISOLATIONPOINT_NOT_FOUND)
33
+
34
+    point.point_fields = fields
35
+    point.limit_scene_qrcode_url = get_point_limit_scene_qrcode_url(point_id)
36
+    point.save()
37
+
38
+    return response()

+ 12 - 0
api/point_views.py

@@ -27,6 +27,18 @@ def measure_window(request):
27 27
 
28 28
 
29 29
 @logit
30
+def get_point_info(request):
31
+    point_id = request.POST.get('point_id', '')
32
+
33
+    try:
34
+        point = IsolationPointInfo.objects.get(point_id=point_id, status=True)
35
+    except IsolationPointInfo.DoesNotExist:
36
+        return response(IsolationPointStatusCode.ISOLATIONPOINT_NOT_FOUND)
37
+
38
+    return response(data=point.data)
39
+
40
+
41
+@logit
30 42
 def get_point_fields(request):
31 43
     point_id = request.POST.get('point_id', '')
32 44
 

+ 15 - 1
api/urls.py

@@ -2,7 +2,7 @@
2 2
 
3 3
 from django.conf.urls import url
4 4
 
5
-from api import admin_views, eqpt_views, mini_views, oauth_views, point_views
5
+from api import admin_views, eqpt_views, field_views, mini_views, oauth_views, point_views, wx_views
6 6
 
7 7
 
8 8
 urlpatterns = [
@@ -14,11 +14,24 @@ urlpatterns += [
14 14
 ]
15 15
 
16 16
 urlpatterns += [
17
+    url(r'^get_limit_scene_qrcode_url$', wx_views.get_limit_scene_qrcode_url, name='get_limit_scene_qrcode_url'),
18
+]
19
+
20
+urlpatterns += [
17 21
     url(r'^admin/login$', admin_views.admin_login, name='admin_login'),
18 22
 ]
19 23
 
20 24
 urlpatterns += [
25
+    url(r'^field/default$', field_views.field_default, name='field_default'),
26
+
27
+    url(r'^point/field/add$', field_views.point_field_update, name='point_field_add'),
28
+    url(r'^point/field/update$', field_views.point_field_update, name='point_field_update'),
29
+]
30
+
31
+urlpatterns += [
21 32
     url(r'^point/measure_window$', point_views.measure_window, name='measure_window'),
33
+
34
+    url(r'^point/info$', point_views.get_point_info, name='point_info'),
22 35
 ]
23 36
 
24 37
 urlpatterns += [
@@ -40,6 +53,7 @@ urlpatterns += [
40 53
 ]
41 54
 
42 55
 urlpatterns += [
56
+    url(r'^mp/get_point_info$', point_views.get_point_info, name='get_point_info'),
43 57
     url(r'^mp/get_point_fields$', point_views.get_point_fields, name='get_point_fields'),
44 58
     url(r'^mp/save_point_fields$', point_views.save_point_fields, name='save_point_fields'),
45 59
     url(r'^mp/bind_eqpt$', point_views.bind_eqpt, name='bind_eqpt'),

+ 49 - 0
api/wx_views.py

@@ -0,0 +1,49 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+from __future__ import division
4
+
5
+from django.conf import settings
6
+from django_response import response
7
+from pywe_qrcode import qrcode_limit_str_scene
8
+from pywe_storage import RedisStorage
9
+
10
+from utils.error.errno_utils import ParamStatusCode
11
+from utils.redis.connect import r
12
+
13
+
14
+def get_limit_scene_qrcode_url(request):
15
+    scene = str(request.GET.get('scene', ''))
16
+
17
+    if not scene:
18
+        return response(ParamStatusCode.PARAM_NOT_FOUND)
19
+
20
+    JSAPI = settings.WECHAT.get('JSAPI', {})
21
+
22
+    appid = JSAPI.get('appID', '')
23
+    appsecret = JSAPI.get('appsecret', '')
24
+
25
+    if not appid:
26
+        return response(ParamStatusCode.PARAM_NOT_FOUND)
27
+
28
+    qrurl = qrcode_limit_str_scene(scene_str=scene, appid=appid, secret=appsecret, storage=RedisStorage(r), qrurl=True)
29
+
30
+    return response(data={
31
+        'qrurl': qrurl,
32
+    })
33
+
34
+
35
+def get_point_limit_scene_qrcode_url(scene):
36
+    if not scene:
37
+        return ''
38
+
39
+    JSAPI = settings.WECHAT.get('JSAPI', {})
40
+
41
+    appid = JSAPI.get('appID', '')
42
+    appsecret = JSAPI.get('appsecret', '')
43
+
44
+    if not appid:
45
+        return ''
46
+
47
+    qrurl = qrcode_limit_str_scene(scene_str=scene, appid=appid, secret=appsecret, storage=RedisStorage(r), qrurl=True, useurl=True)
48
+
49
+    return qrurl

+ 7 - 2
equipment/admin.py

@@ -3,8 +3,12 @@
3 3
 from django.contrib import admin
4 4
 from django_admin import ReadOnlyModelAdmin
5 5
 
6
-from equipment.models import (IsolationPointInfo, IsolationPointUserInfo, ThermometerEquipmentInfo,
7
-                              ThermometerMeasureInfo, ThermometerMeasureLogInfo)
6
+from equipment.models import (IsolationPointFieldPoolInfo, IsolationPointInfo, IsolationPointUserInfo,
7
+                              ThermometerEquipmentInfo, ThermometerMeasureInfo, ThermometerMeasureLogInfo)
8
+
9
+
10
+class IsolationPointFieldPoolInfoAdmin(admin.ModelAdmin):
11
+    list_display = ('field_type', 'field_key', 'field_name', 'field_options', 'status', 'updated_at', 'created_at')
8 12
 
9 13
 
10 14
 class IsolationPointInfoAdmin(admin.ModelAdmin):
@@ -30,6 +34,7 @@ class ThermometerMeasureLogInfoAdmin(ReadOnlyModelAdmin, admin.ModelAdmin):
30 34
     list_filter = ('point_id', 'temperature_src', 'status')
31 35
 
32 36
 
37
+admin.site.register(IsolationPointFieldPoolInfo, IsolationPointFieldPoolInfoAdmin)
33 38
 admin.site.register(IsolationPointInfo, IsolationPointInfoAdmin)
34 39
 admin.site.register(IsolationPointUserInfo, IsolationPointUserInfoAdmin)
35 40
 admin.site.register(ThermometerEquipmentInfo, ThermometerEquipmentInfoAdmin)

+ 31 - 0
equipment/migrations/0007_isolationpointfieldpoolinfo.py

@@ -0,0 +1,31 @@
1
+# Generated by Django 3.2.6 on 2021-08-14 19:56
2
+
3
+from django.db import migrations, models
4
+import jsonfield.fields
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('equipment', '0006_auto_20210812_1357'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.CreateModel(
15
+            name='IsolationPointFieldPoolInfo',
16
+            fields=[
17
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
18
+                ('status', models.BooleanField(default=True, help_text='Status', verbose_name='status')),
19
+                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
20
+                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
21
+                ('field_type', models.CharField(choices=[('input', 'input'), ('select', 'select'), ('file', 'file')], default='input', help_text='字段类型', max_length=8, verbose_name='field_type')),
22
+                ('field_name', models.CharField(blank=True, help_text='字段名称', max_length=32, null=True, verbose_name='field_name')),
23
+                ('field_key', models.CharField(blank=True, help_text='字段键值', max_length=32, null=True, verbose_name='field_key')),
24
+                ('field_options', jsonfield.fields.JSONField(blank=True, default=[], help_text='字段选择', null=True, verbose_name='field_options')),
25
+            ],
26
+            options={
27
+                'verbose_name': '用户字段池信息',
28
+                'verbose_name_plural': '用户字段池信息',
29
+            },
30
+        ),
31
+    ]

+ 46 - 3
equipment/models.py

@@ -7,14 +7,51 @@ from jsonfield import JSONField
7 7
 from shortuuidfield import ShortUUIDField
8 8
 from TimeConvert import TimeConvert as tc
9 9
 
10
+from utils.redis.rqrurl import get_qrcode_url
11
+
12
+
13
+class IsolationPointFieldPoolInfo(BaseModelMixin):
14
+    INPUT = 'input'
15
+    SELECT = 'select'
16
+    FILE = 'file'
17
+
18
+    FIELD_TYPE_TUPLE = (
19
+        (INPUT, 'input'),
20
+        (SELECT, 'select'),
21
+        (FILE, 'file'),
22
+    )
23
+
24
+    # {
25
+    #     "type": "input",  # input, select, file
26
+    #     "name": "",
27
+    #     "options": ["男", "女"],  # type=select
28
+    # }
29
+    field_type = models.CharField(_('field_type'), max_length=8, choices=FIELD_TYPE_TUPLE, default=INPUT, help_text='字段类型')
30
+    field_name = models.CharField(_('field_name'), max_length=32, blank=True, null=True, help_text='字段名称')
31
+    field_key = models.CharField(_('field_key'), max_length=32, blank=True, null=True, help_text='字段键值')
32
+    field_options = JSONField(_('field_options'), default=[], blank=True, null=True, help_text='字段选择')
33
+
34
+    class Meta:
35
+        verbose_name = _('用户字段池信息')
36
+        verbose_name_plural = _('用户字段池信息')
37
+
38
+    def __unicode__(self):
39
+        return self.pk
40
+
41
+    @property
42
+    def data(self):
43
+        return {
44
+            'type': self.field_type,
45
+            'key': self.field_key,
46
+            'name': self.field_name,
47
+            'options': self.field_options,
48
+        }
49
+
10 50
 
11 51
 class IsolationPointInfo(BaseModelMixin):
12 52
     point_id = ShortUUIDField(_('point_id'), max_length=32, blank=True, null=True, help_text='隔离点唯一标识', db_index=True, unique=True)
13 53
     point_name = models.CharField(_('point_name'), max_length=255, blank=True, null=True, help_text='隔离点名称')
14 54
 
15
-    # [{"start": "8:00", "end": "9:00"}, {"start": "12:00", "end": "14:00"}]
16
-    point_measure_window = JSONField(_('point_measure_window'), default=[], blank=True, null=True, help_text='隔离点测温时间段')
17
-
18 55
     # {
19 56
     #     "type": "input",  # input, select, file
20 57
     #     "name": "",
@@ -22,6 +59,9 @@ class IsolationPointInfo(BaseModelMixin):
22 59
     # }
23 60
     point_fields = JSONField(_('point_fields'), default=[], blank=True, null=True, help_text='字段列表')
24 61
 
62
+    # [{"start": "8:00", "end": "9:00"}, {"start": "12:00", "end": "14:00"}]
63
+    point_measure_window = JSONField(_('point_measure_window'), default=[], blank=True, null=True, help_text='隔离点测温时间段')
64
+
25 65
     limit_scene_qrcode_url = models.CharField(_('limit_scene_qrcode_url'), max_length=255, blank=True, null=True, help_text='字段二维码')
26 66
 
27 67
     class Meta:
@@ -33,10 +73,13 @@ class IsolationPointInfo(BaseModelMixin):
33 73
 
34 74
     @property
35 75
     def data(self):
76
+        qrcode_url = get_qrcode_url(self.point_id)
36 77
         return {
37 78
             'point_id': self.point_id,
38 79
             'point_name': self.point_name,
80
+            'point_fields': self.point_fields,
39 81
             'point_measure_window': self.point_measure_window,
82
+            'qrcode_url': qrcode_url,
40 83
         }
41 84
 
42 85
     @property

+ 1 - 0
requirements_pywe.txt

@@ -1,4 +1,5 @@
1 1
 pywe-miniapp==1.1.6
2 2
 pywe-oauth==1.1.1
3 3
 pywe-pay==1.0.14
4
+pywe-qrcode==1.0.3
4 5
 pywe-storage==1.0.1

+ 2 - 0
utils/redis/rkeys.py

@@ -1 +1,3 @@
1 1
 # -*- coding: utf-8 -*-
2
+
3
+HY_QRCODE_URL_HASH = 'twjc:qrcode:url:hash'  # scene:qrcode_url

+ 19 - 0
utils/redis/rqrurl.py

@@ -0,0 +1,19 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+from api.wx_views import get_point_limit_scene_qrcode_url
4
+from utils.redis.connect import r
5
+from utils.redis.rkeys import HY_QRCODE_URL_HASH
6
+
7
+
8
+def set_qrcode_url(scene):
9
+    qrcode_url = get_point_limit_scene_qrcode_url(scene)
10
+    if qrcode_url:
11
+        try:
12
+            r.hset(HY_QRCODE_URL_HASH, scene, qrcode_url)
13
+        except Exception as e:
14
+            pass
15
+    return qrcode_url
16
+
17
+
18
+def get_qrcode_url(scene):
19
+    return r.hget(HY_QRCODE_URL_HASH, scene) or set_qrcode_url(scene)